/*
 * Copyright (c) 2016 Fingerprint Cards AB <tech@fingerprints.com>
 *
 * All rights are reserved.
 * Proprietary and confidential.
 * Unauthorized copying of this file, via any medium is strictly prohibited.
 * Any use is subject to an appropriate license granted by Fingerprint Cards AB.
 */

#ifndef FPC_BEP_SENSOR_TEST_H
#define FPC_BEP_SENSOR_TEST_H

/**
 * @file    fpc_bep_sensor_test.h
 * @brief   BEP sensor production test functions.
 *
 * Check for sensor damage during production test.
 *
 * @note Before using this API the sensor must be initialized, see
 * fpc_bep_sensor_init().
 *
 * @note This is a work-in-progress specification. Implementers are informed
 * that this API may change without providing any backward compatibility.
 * However it is FPC's ambition that the API shall remain compatible between
 * releases.
 */

#include <stdint.h>

#include "fpc_bep_types.h"

/**
 * @brief Test image size.
 */
typedef enum {
    /** Capture test image using all sensor pixels. */
    FPC_BEP_TEST_IMAGE_LARGE  = 0,
    /** Capture test image using 1/4 of all the sensor pixels */
    FPC_BEP_TEST_IMAGE_MEDIUM = 1,
    /** Capture test image using 1/16 of all the sensor pixels */
    FPC_BEP_TEST_IMAGE_SMALL  = 2,
} fpc_bep_test_image_size_t;

/**
 * @brief Capture test modes.
 */
typedef enum {
    /** Capture test image using reset test mode. */
    FPC_BEP_CAPTURE_TEST_MODE_RESET = 0,
    /** Capture test image using checkerboard test mode. */
    FPC_BEP_CAPTURE_TEST_MODE_CHECKERBOARD = 1,
    /** Capture test image using checkerboard inverted test mode. */
    FPC_BEP_CAPTURE_TEST_MODE_CHECKERBOARD_INVERTED = 2,
} fpc_bep_capture_test_mode_t;

/**
 * @brief Contrast test result.
 */
typedef struct {
    /** Max standard deviation. */
    float max_std_dev;
    /** Min standard deviation. */
    float min_std_dev;
    /** Average standard deviation. */
    float avg_std_dev;
    /** Total number of sub areas. */
    uint32_t total_subareas;
} fpc_bep_contrast_result_t;

/**
 * @brief Analyze reset subtest result.
 */
typedef struct {
    /** Number of defective pixels. */
    uint16_t num_of_defect_pixels;
    /** Median. */
    uint8_t median;
    /** Padding to achieve 32bit  */
    uint8_t dummy;
} fpc_bep_analyze_reset_result_t;

/**
 * @brief Analyze checkerboard and inverted chechekboard subtest result.
 */
typedef struct {
    /** Number of defective pixels. */
    uint16_t num_of_defect_pixels;
    /** Number of defective pixels in detect_zones. */
    uint16_t num_of_defect_pixels_in_detect_zones;
    /** Min of median type 1 if gradient, median type 1 if legacy. */
    uint8_t median_type1_min;
    /** Max of median type 1 if gradient, median type 1 (duplicate) if legacy. */
    uint8_t median_type1_max;
    /** Min of median type 2 if gradient, median type 2 if legacy. */
    uint8_t median_type2_min;
    /** Max of median type 2 if gradient, median type 2 (duplicate) if legacy. */
    uint8_t median_type2_max;
} fpc_bep_analyze_cb_result_t;

/**
 * @brief Analyze test result.
 */
typedef union {
    fpc_bep_analyze_reset_result_t reset;
    fpc_bep_analyze_cb_result_t cb;
    fpc_bep_analyze_cb_result_t icb;
} fpc_bep_analyze_result_t;

/**
 * @brief Sensor production test
 *
 * The test checks that the module meets the requirements.
 * The following tests are performed:
 *   - Checkerboard test and inverted checkerboard test
 *   - Reset pixel test (only for applicable sensors)
 *
 * To find any dead pixels, checkerboard and reset pixels images are captured and processed by BEP.
 * If too many dead pixels are found the test will fail. The number of dead pixels available as a
 * log output only while using libbep_diag.a
 *
 * @return ::fpc_bep_result_t
 */
fpc_bep_result_t fpc_bep_sensor_prod_test(void);

/**
 * @brief Captures an image during production test
 *
 * This function will put the sensor in idle mode and then capture an image regardless of the
 * sensor coverage.
 *
 * This is mainly used for testing connectivity of the bezel and is only supported for older
 * sensors without companion chip.
 *
 * @param[in] image_size Image capture size. The smaller size, the shorter time for image capture.
 * @return ::fpc_bep_result_t
 */
fpc_bep_result_t fpc_bep_sensor_prod_test_capture(fpc_bep_test_image_size_t image_size);

/**
 * @brief Captures an image using one of the capture test modes
 *
 * This function will put the sensor in idle mode and then capture an image using the selected
 * mode ::fpc_bep_capture_test_mode_t.
 *
 * This can be useful to evaluate the images outside the lib.
 *
 * @param[in,out] image The captured image.
 * @param[in] mode Image capture test mode.
 * @return ::fpc_bep_result_t
 */
fpc_bep_result_t fpc_bep_sensor_prod_test_mode_capture(fpc_bep_image_t *image,
    fpc_bep_capture_test_mode_t mode);

/**
 * @brief Analyze image captured in test mode
 *
 * This function will analyze the image for the selected mode and report back if too many
 * dead pixels were detected. The image must have been captured with the selected mode using
 * ::fpc_bep_sensor_prod_test_mode_capture.
 * mode ::fpc_bep_capture_test_mode_t.
 *
 * @param[in,out] image The captured image.
 * @param[in] mode Image capture test mode.
 * @param[in,out] test_result ::fpc_bep_anaylyze_result_t.
 * @return ::fpc_bep_result_t
 */
fpc_bep_result_t fpc_bep_sensor_prod_test_mode_analyze(fpc_bep_image_t *image,
    fpc_bep_capture_test_mode_t mode, fpc_bep_analyze_result_t *test_result);

/**
 * @brief Run contrast test on image
 *
 * This function will run constrast test on image. The image must have been captured with
 * ::fpc_bep_capture using a zebra stamp.
 *
 * @param[in,out] image The captured image.
 * @param[in,out] test_result ::fpc_bep_contrast_result_t.
 * @return ::fpc_bep_result_t
 */
fpc_bep_result_t fpc_bep_sensor_prod_test_contrast(fpc_bep_image_t *image,
    fpc_bep_contrast_result_t *test_result);

/**
 * @brief Run Otp test
 *
 * This function reads out the otp memory and verifies that it is populated with data.
 *
 * @return :: fpc_bep_result_t
 */
fpc_bep_result_t fpc_bep_sensor_otp_test(void);

#endif /* FPC_BEP_SENSOR_TEST_H */
